package app

import (
	"html/template"
	"log"
	"net/http"
	"os"
	"strings"

	assetfs "github.com/elazarl/go-bindata-assetfs"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
)

// App 应用.
type App struct {
	r  *gin.Engine
	dc *DisplayCtrl
}

func loadTemplate() (*template.Template, error) {
	t := template.New("")

	for _, name := range AssetNames() {
		if !strings.HasSuffix(name, ".tmpl") {
			continue
		}

		bs, err := Asset(name)
		if err != nil {
			return nil, err
		}

		t, err = t.New(name).Parse(string(bs))
		if err != nil {
			return nil, err
		}
	}

	return t, nil
}

// NewApp 新应用.
func NewApp(
	dc *DisplayCtrl,
) *App {
	r := gin.Default()
	r.Use(cors.New(cors.Config{
		AllowOrigins:     []string{"*"},
		AllowMethods:     []string{"HEAD", "GET", "POST", "PUT", "DELETE"},
		AllowCredentials: true,
		AllowHeaders:     []string{"Content-Type"},
	}))
	// 模板
	t, err := loadTemplate()
	if err != nil {
		log.Fatal(err)
	}

	r.SetHTMLTemplate(t)
	// 静态资源
	r.StaticFS("/assets", &assetfs.AssetFS{
		Asset:     Asset,
		AssetDir:  AssetDir,
		AssetInfo: AssetInfo,
		Prefix:    "assets",
	})
	r.Static("/files", "./files")

	a := &App{
		r:  r,
		dc: dc,
	}
	a.initRoutes()

	return a
}

// Run 应用.
func (a *App) Run() {
	port := os.Getenv("DS_PORT")
	if port == "" {
		port = ":8080"
	}

	if !strings.HasPrefix(port, ":") {
		port = ":" + port
	}

	for _, d := range a.dc.cs.displays {
		log.Printf("请在浏览器中打开: http://localhost%s/display/%d", port, d.Id)
	}

	log.Fatal(http.ListenAndServe(port, a.r))
}

func (a *App) initRoutes() {
	api := a.r.Group("/api")
	{
		// 探针
		api.GET("/ping", a.Ping)
	}
	// 显示屏
	a.r.GET("/display/:id", a.dc.Display)
	// WebSocket
	a.r.GET("/ws", a.dc.WebSocket)
}

// Ping 访问检查.
// swagger:operation GET /ping app ping
// ---
// summary: 访问检查
// description: 探针
// responses:
//   200:
//     description: 访问成功
//     schema:
//       $ref: "#/definitions/Message"
func (a *App) Ping(c *gin.Context) {
	OK(c, "pong")
}
